// CZ 编译器自定义标准库
// 为了简化和兼容性，直接使用 std.mem.Allocator

const std = @import("std");

// ============ 内存分配 ============

// 直接使用 std.mem.Allocator，避免复杂的类型转换
pub const Allocator = std.mem.Allocator;

// ============ 数据结构 ============

pub const ArrayList = @import("array_list.zig").ArrayList;

// ============ 字符串操作 ============

pub const StringMap = struct {
    const Entry = struct {
        key: []const u8,
        value: []const u8,
    };
    
    entries: []const Entry,
    
    pub fn init(entries: []const Entry) StringMap {
        return .{ .entries = entries };
    }
    
    pub fn get(self: StringMap, key: []const u8) ?[]const u8 {
        for (self.entries) |entry| {
            if (eql(entry.key, key)) {
                return entry.value;
            }
        }
        return null;
    }
};

pub fn eql(a: []const u8, b: []const u8) bool {
    if (a.len != b.len) return false;
    for (a, b) |ca, cb| {
        if (ca != cb) return false;
    }
    return true;
}

pub fn indexOf(haystack: []const u8, needle: []const u8) ?usize {
    if (needle.len == 0) return 0;
    if (needle.len > haystack.len) return null;
    
    var i: usize = 0;
    while (i <= haystack.len - needle.len) : (i += 1) {
        if (eql(haystack[i..i + needle.len], needle)) {
            return i;
        }
    }
    return null;
}

pub fn startsWith(haystack: []const u8, needle: []const u8) bool {
    if (needle.len > haystack.len) return false;
    return eql(haystack[0..needle.len], needle);
}

pub fn endsWith(haystack: []const u8, needle: []const u8) bool {
    if (needle.len > haystack.len) return false;
    return eql(haystack[haystack.len - needle.len..], needle);
}

// ============ 字符串构建器 ============

pub const StringBuilder = struct {
    buffer: ArrayList(u8),
    
    pub fn init(allocator: Allocator) StringBuilder {
        return .{
            .buffer = ArrayList(u8).init(allocator),
        };
    }
    
    pub fn deinit(self: *StringBuilder) void {
        self.buffer.deinit();
    }
    
    pub fn append(self: *StringBuilder, str: []const u8) !void {
        for (str) |c| {
            try self.buffer.append(c);
        }
    }
    
    pub fn appendChar(self: *StringBuilder, c: u8) !void {
        try self.buffer.append(c);
    }
    
    pub fn appendFmt(self: *StringBuilder, comptime fmt: []const u8, args: anytype) !void {
        var buf: [4096]u8 = undefined;
        const result = try bufPrint(&buf, fmt, args);
        try self.append(result);
    }
    
    pub fn toOwnedSlice(self: *StringBuilder) ![]u8 {
        return try self.buffer.toOwnedSlice();
    }
    
    pub fn items(self: *StringBuilder) []const u8 {
        return self.buffer.items;
    }
    
    pub fn len(self: *StringBuilder) usize {
        return self.buffer.items.len;
    }
    
    pub fn clear(self: *StringBuilder) void {
        self.buffer.items.len = 0;
    }
};

// ============ HashMap ============

pub fn HashMap(comptime K: type, comptime V: type) type {
    return struct {
        const Self = @This();
        const Entry = struct {
            key: K,
            value: V,
            used: bool,
        };
        
        entries: []Entry,
        count: usize,
        allocator: Allocator,
        
        pub fn init(allocator: Allocator) !Self {
            const initial_capacity = 16;
            const entries = try allocator.alloc(Entry, initial_capacity);
            for (entries) |*entry| {
                entry.used = false;
            }
            return Self{
                .entries = entries,
                .count = 0,
                .allocator = allocator,
            };
        }
        
        pub fn deinit(self: *Self) void {
            self.allocator.free(self.entries);
        }
        
        pub fn put(self: *Self, key: K, value: V) !void {
            if (self.count * 2 >= self.entries.len) {
                try self.resize();
            }
            
            const hash_value = hash(key);
            var idx = hash_value % self.entries.len;
            
            while (self.entries[idx].used) {
                if (keyEql(self.entries[idx].key, key)) {
                    self.entries[idx].value = value;
                    return;
                }
                idx = (idx + 1) % self.entries.len;
            }
            
            self.entries[idx] = .{
                .key = key,
                .value = value,
                .used = true,
            };
            self.count += 1;
        }
        
        pub fn get(self: *Self, key: K) ?V {
            const hash_value = hash(key);
            var idx = hash_value % self.entries.len;
            var tries: usize = 0;
            
            while (tries < self.entries.len) : (tries += 1) {
                if (!self.entries[idx].used) {
                    return null;
                }
                if (keyEql(self.entries[idx].key, key)) {
                    return self.entries[idx].value;
                }
                idx = (idx + 1) % self.entries.len;
            }
            return null;
        }
        
        fn resize(self: *Self) !void {
            const new_capacity = self.entries.len * 2;
            const new_entries = try self.allocator.alloc(Entry, new_capacity);
            for (new_entries) |*entry| {
                entry.used = false;
            }
            
            const old_entries = self.entries;
            self.entries = new_entries;
            self.count = 0;
            
            for (old_entries) |entry| {
                if (entry.used) {
                    try self.put(entry.key, entry.value);
                }
            }
            
            self.allocator.free(old_entries);
        }
        
        fn hash(key: K) usize {
            if (K == []const u8) {
                var h: usize = 5381;
                for (key) |c| {
                    h = ((h << 5) +% h) +% c;
                }
                return h;
            } else {
                return @intCast(@as(isize, @bitCast(key)));
            }
        }
        
        fn keyEql(a: K, b: K) bool {
            if (K == []const u8) {
                return eql(a, b);
            } else {
                return a == b;
            }
        }
    };
}

// ============ 文件操作 ============
// 注意：这些函数需要外部 C 库支持

pub fn readFile(allocator: Allocator, path: []const u8) ![]u8 {
    _ = allocator;
    _ = path;
    return error.NotImplemented;
}

pub fn writeFile(path: []const u8, content: []const u8) !void {
    _ = path;
    _ = content;
    return error.NotImplemented;
}

// ============ 格式化输出 ============

pub fn print(comptime fmt: []const u8, args: anytype) void {
    _ = fmt;
    _ = args;
    // 简化实现：不输出
}

// 简单的格式化函数
pub fn format(allocator: Allocator, comptime fmt: []const u8, args: anytype) ![]u8 {
    var sb = StringBuilder.init(allocator);
    defer sb.deinit();
    
    try formatToWriter(&sb, fmt, args);
    return try sb.toOwnedSlice();
}

pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) ![]u8 {
    // 使用 std.fmt.bufPrint 来处理格式化
    return std.fmt.bufPrint(buf, fmt, args);
}

fn formatToWriter(writer: *StringBuilder, comptime fmt: []const u8, args: anytype) !void {
    _ = args;
    try writer.append(fmt);
}

fn intToString(buf: []u8, value: i64) ![]u8 {
    if (value == 0) {
        buf[0] = '0';
        return buf[0..1];
    }
    
    var num = value;
    var is_negative = false;
    if (num < 0) {
        is_negative = true;
        num = -num;
    }
    
    var pos: usize = 0;
    var temp_buf: [32]u8 = undefined;
    
    while (num > 0) {
        temp_buf[pos] = @intCast((num % 10) + '0');
        num = @divTrunc(num, 10);
        pos += 1;
    }
    
    var result_pos: usize = 0;
    if (is_negative) {
        buf[result_pos] = '-';
        result_pos += 1;
    }
    
    while (pos > 0) {
        pos -= 1;
        buf[result_pos] = temp_buf[pos];
        result_pos += 1;
    }
    
    return buf[0..result_pos];
}

// 解析整数 - 使用 std.fmt.parseInt
pub fn parseInt(comptime T: type, str: []const u8, base: u8) !T {
    return std.fmt.parseInt(T, str, base);
}

// 解析浮点数 - 使用 std.fmt.parseFloat
pub fn parseFloat(comptime T: type, str: []const u8) !T {
    return std.fmt.parseFloat(T, str);
}

// ============ 进程操作 ============

pub const ProcessResult = struct {
    stdout: []u8,
    stderr: []u8,
    exit_code: u8,
    allocator: Allocator,
    
    pub fn deinit(self: *ProcessResult) void {
        self.allocator.free(self.stdout);
        self.allocator.free(self.stderr);
    }
};

pub fn runCommand(allocator: Allocator, argv: []const []const u8) !ProcessResult {
    _ = allocator;
    _ = argv;
    return error.NotImplemented;
}



// ============ 内存操作 ============

pub fn memcpy(dest: []u8, src: []const u8) void {
    for (src, 0..) |byte, i| {
        if (i >= dest.len) break;
        dest[i] = byte;
    }
}

pub fn memset(dest: []u8, value: u8) void {
    for (dest) |*byte| {
        byte.* = value;
    }
}

pub fn memcmp(a: []const u8, b: []const u8) i32 {
    const min_len = if (a.len < b.len) a.len else b.len;
    for (a[0..min_len], b[0..min_len]) |ca, cb| {
        if (ca < cb) return -1;
        if (ca > cb) return 1;
    }
    if (a.len < b.len) return -1;
    if (a.len > b.len) return 1;
    return 0;
}

pub fn memmove(dest: []u8, src: []const u8) void {
    if (dest.ptr == src.ptr) return;
    
    // 检查是否重叠
    const dest_start = @intFromPtr(dest.ptr);
    const dest_end = dest_start + dest.len;
    const src_start = @intFromPtr(src.ptr);
    
    if (dest_start < src_start and dest_end > src_start) {
        // 从后向前复制
        var i = if (dest.len < src.len) dest.len else src.len;
        while (i > 0) {
            i -= 1;
            dest[i] = src[i];
        }
    } else {
        // 从前向后复制
        memcpy(dest, src);
    }
}

// ============ 字符串高级操作 ============

pub fn split(allocator: Allocator, str: []const u8, delimiter: []const u8) ![][]const u8 {
    var result = ArrayList([]const u8).init(allocator);
    defer result.deinit();
    
    var start: usize = 0;
    while (start < str.len) {
        if (indexOf(str[start..], delimiter)) |pos| {
            try result.append(str[start..start + pos]);
            start += pos + delimiter.len;
        } else {
            try result.append(str[start..]);
            break;
        }
    }
    
    return try result.toOwnedSlice();
}

pub fn join(allocator: Allocator, parts: []const []const u8, separator: []const u8) ![]u8 {
    if (parts.len == 0) return try allocator.alloc(u8, 0);
    
    // 计算总长度
    var total_len: usize = 0;
    for (parts, 0..) |part, i| {
        total_len += part.len;
        if (i < parts.len - 1) {
            total_len += separator.len;
        }
    }
    
    // 分配内存
    var result = try allocator.alloc(u8, total_len);
    var pos: usize = 0;
    
    // 拼接字符串
    for (parts, 0..) |part, i| {
        memcpy(result[pos..], part);
        pos += part.len;
        if (i < parts.len - 1) {
            memcpy(result[pos..], separator);
            pos += separator.len;
        }
    }
    
    return result;
}

pub fn trim(str: []const u8) []const u8 {
    return trimRight(trimLeft(str));
}

pub fn trimLeft(str: []const u8) []const u8 {
    var start: usize = 0;
    while (start < str.len and isWhitespace(str[start])) {
        start += 1;
    }
    return str[start..];
}

pub fn trimRight(str: []const u8) []const u8 {
    var end: usize = str.len;
    while (end > 0 and isWhitespace(str[end - 1])) {
        end -= 1;
    }
    return str[0..end];
}

pub fn isWhitespace(c: u8) bool {
    return c == ' ' or c == '\t' or c == '\n' or c == '\r';
}

pub fn toLower(allocator: Allocator, str: []const u8) ![]u8 {
    var result = try allocator.alloc(u8, str.len);
    for (str, 0..) |c, i| {
        result[i] = if (c >= 'A' and c <= 'Z') c + 32 else c;
    }
    return result;
}

pub fn toUpper(allocator: Allocator, str: []const u8) ![]u8 {
    var result = try allocator.alloc(u8, str.len);
    for (str, 0..) |c, i| {
        result[i] = if (c >= 'a' and c <= 'z') c - 32 else c;
    }
    return result;
}

pub fn replace(allocator: Allocator, str: []const u8, old: []const u8, new: []const u8) ![]u8 {
    if (old.len == 0) return try allocator.dupe(u8, str);
    
    // 计算替换次数
    var replace_count: usize = 0; // 重命名以避免与count函数冲突
    var pos: usize = 0;
    while (pos < str.len) {
        if (indexOf(str[pos..], old)) |found| {
            replace_count += 1;
            pos += found + old.len;
        } else {
            break;
        }
    }
    
    if (replace_count == 0) return try allocator.dupe(u8, str);
    
    // 计算新字符串长度
    const new_len = str.len - (replace_count * old.len) + (replace_count * new.len);
    var result = try allocator.alloc(u8, new_len);
    
    // 执行替换
    var src_pos: usize = 0;
    var dst_pos: usize = 0;
    while (src_pos < str.len) {
        if (indexOf(str[src_pos..], old)) |found| {
            // 复制前面的部分
            memcpy(result[dst_pos..], str[src_pos..src_pos + found]);
            dst_pos += found;
            // 复制新字符串
            memcpy(result[dst_pos..], new);
            dst_pos += new.len;
            src_pos += found + old.len;
        } else {
            // 复制剩余部分
            memcpy(result[dst_pos..], str[src_pos..]);
            break;
        }
    }
    
    return result;
}

pub fn contains(haystack: []const u8, needle: []const u8) bool {
    return indexOf(haystack, needle) != null;
}

pub fn count(haystack: []const u8, needle: []const u8) usize {
    if (needle.len == 0) return 0;
    
    var result: usize = 0;
    var pos: usize = 0;
    while (pos < haystack.len) {
        if (indexOf(haystack[pos..], needle)) |found| {
            result += 1;
            pos += found + needle.len;
        } else {
            break;
        }
    }
    return result;
}

// ============ 数学函数 ============

pub fn min(comptime T: type, a: T, b: T) T {
    return if (a < b) a else b;
}

pub fn max(comptime T: type, a: T, b: T) T {
    return if (a > b) a else b;
}

pub fn abs(comptime T: type, x: T) T {
    return if (x < 0) -x else x;
}

pub fn clamp(comptime T: type, value: T, low: T, high: T) T {
    return max(T, low, min(T, value, high));
}

// ============ 切片操作 ============

pub fn reverse(comptime T: type, slice: []T) void {
    var i: usize = 0;
    var j: usize = slice.len;
    while (i < j) {
        j -= 1;
        const temp = slice[i];
        slice[i] = slice[j];
        slice[j] = temp;
        i += 1;
    }
}

pub fn fill(comptime T: type, slice: []T, value: T) void {
    for (slice) |*item| {
        item.* = value;
    }
}

pub fn copy(comptime T: type, dest: []T, src: []const T) usize {
    const n = min(usize, dest.len, src.len);
    for (src[0..n], 0..) |item, i| {
        dest[i] = item;
    }
    return n;
}

// ============ 排序 ============

pub fn sort(comptime T: type, slice: []T, comptime lessThan: fn (T, T) bool) void {
    if (slice.len <= 1) return;
    quickSort(T, slice, 0, slice.len - 1, lessThan);
}

fn quickSort(comptime T: type, slice: []T, low: usize, high: usize, comptime lessThan: fn (T, T) bool) void {
    if (low >= high) return;
    
    const pivot_idx = partition(T, slice, low, high, lessThan);
    if (pivot_idx > 0) {
        quickSort(T, slice, low, pivot_idx - 1, lessThan);
    }
    if (pivot_idx < high) {
        quickSort(T, slice, pivot_idx + 1, high, lessThan);
    }
}

fn partition(comptime T: type, slice: []T, low: usize, high: usize, comptime lessThan: fn (T, T) bool) usize {
    const pivot = slice[high];
    var i = low;
    
    var j = low;
    while (j < high) : (j += 1) {
        if (lessThan(slice[j], pivot)) {
            const temp = slice[i];
            slice[i] = slice[j];
            slice[j] = temp;
            i += 1;
        }
    }
    
    const temp = slice[i];
    slice[i] = slice[high];
    slice[high] = temp;
    
    return i;
}

// ============ 随机数 ============

pub const Random = struct {
    state: u64,
    
    pub fn init(seed: u64) Random {
        return Random{ .state = seed };
    }
    
    pub fn next(self: *Random) u64 {
        // Xorshift64
        var x = self.state;
        x ^= x << 13;
        x ^= x >> 7;
        x ^= x << 17;
        self.state = x;
        return x;
    }
    
    pub fn intRange(self: *Random, comptime T: type, min_val: T, max_val: T) T {
        const range = max_val - min_val;
        const rand_val = self.next();
        return min_val + @as(T, @intCast(rand_val % @as(u64, @intCast(range))));
    }
    
    pub fn boolean(self: *Random) bool {
        return (self.next() & 1) == 1;
    }
    
    pub fn float(self: *Random, comptime T: type) T {
        const rand_val = self.next();
        return @as(T, @floatFromInt(rand_val)) / @as(T, @floatFromInt(@as(u64, 0xFFFFFFFFFFFFFFFF)));
    }
};

// ============ 时间相关 ============

pub fn timestamp() i64 {
    return std.time.timestamp();
}

pub fn milliTimestamp() i64 {
    return std.time.milliTimestamp();
}

pub fn nanoTimestamp() i128 {
    return std.time.nanoTimestamp();
}

// ============ 错误处理 ============

pub const Error = error{
    OutOfMemory,
    InvalidArgument,
    NotFound,
    AlreadyExists,
    PermissionDenied,
    Timeout,
    NotImplemented,
    ParseError,
    InvalidFormat,
    BufferTooSmall,
};

// ============ 选项类型 ============

pub fn Option(comptime T: type) type {
    return struct {
        const Self = @This();
        
        value: ?T,
        
        pub fn some(val: T) Self {
            return Self{ .value = val };
        }
        
        pub fn none() Self {
            return Self{ .value = null };
        }
        
        pub fn isSome(self: Self) bool {
            return self.value != null;
        }
        
        pub fn isNone(self: Self) bool {
            return self.value == null;
        }
        
        pub fn unwrap(self: Self) T {
            return self.value.?;
        }
        
        pub fn unwrapOr(self: Self, default: T) T {
            return self.value orelse default;
        }
    };
}

// ============ 结果类型 ============

pub fn Result(comptime T: type, comptime E: type) type {
    return union(enum) {
        ok: T,
        err: E,
        
        const Self = @This();
        
        pub fn isOk(self: Self) bool {
            return self == .ok;
        }
        
        pub fn isErr(self: Self) bool {
            return self == .err;
        }
        
        pub fn unwrap(self: Self) T {
            return switch (self) {
                .ok => |val| val,
                .err => unreachable,
            };
        }
        
        pub fn unwrapErr(self: Self) E {
            return switch (self) {
                .ok => unreachable,
                .err => |e| e,
            };
        }
    };
}
